package config

import (
	"fmt"

	"github.com/spf13/viper"
)

type DepartmentConfig struct {
	AccessKeyId          string `mapstructure:"ALIBABA_CLOUD_ACCESS_KEY_ID"`
	AccessKeySecret      string `mapstructure:"ALIBABA_CLOUD_ACCESS_KEY_SECRET"`
	Endpoint             string `mapstructure:"ALIBABA_CLOUD_ECI_ENDPOINT"`
	RegionId             string `mapstructure:"ALIBABA_CLOUD_REGION_ID"`
	SecurityGroupId      string `mapstructure:"ALIBABA_CLOUD_SECURITY_GROUP_ID"`
	VSwitchId            string `mapstructure:"ALIBABA_CLOUD_VSWITCH_ID"`
	ImageCacheNamePrefix string `mapstructure:"IMAGE_CACHE_NAME_PREFIX"`
	ImageCacheSize       int32  `mapstructure:"IMAGE_CACHE_SIZE"`
	RetentionDays        int32  `mapstructure:"RetentionDays"`
	AutoMatchImageCache  bool   `mapstructure:"AutoMatchImageCache"`
}

type BasicConfig struct {
	LogFile       string `mapstructure:"LOG_FILE"`
	LogLevel      string `mapstructure:"LOG_LEVEL"`
	RedisAddr     string `mapstructure:"REDIS_ADDR"`
	RedisUsername string `mapstructure:"REDIS_USERNAME"`
	RedisPassword string `mapstructure:"REDIS_PASSWORD"`
	RedisDB       int    `mapstructure:"REDIS_DB"`
}

type Config struct {
	Basic BasicConfig                 `mapstructure:"basic"`
	ECI   map[string]DepartmentConfig `mapstructure:"ECI"`
}

func checkConfig(department string, config DepartmentConfig) error {
	if config.AccessKeyId == "" {
		return fmt.Errorf("configuration error: ALIBABA_CLOUD_ACCESS_KEY_ID in department %s must not be empty", department)
	}
	if config.AccessKeySecret == "" {
		return fmt.Errorf("configuration error: ALIBABA_CLOUD_ACCESS_KEY_SECRET in department %s must not be empty", department)
	}
	if config.Endpoint == "" {
		return fmt.Errorf("configuration error: ALIBABA_CLOUD_ECI_ENDPOINT in department %s must not be empty", department)
	}
	if config.RegionId == "" {
		return fmt.Errorf("configuration error: ALIBABA_CLOUD_REGION_ID in department %s must not be empty", department)
	}
	if config.SecurityGroupId == "" {
		return fmt.Errorf("configuration error: ALIBABA_CLOUD_SECURITY_GROUP_ID in department %s must not be empty", department)
	}
	if config.VSwitchId == "" {
		return fmt.Errorf("configuration error: ALIBABA_CLOUD_VSWITCH_ID in department %s must not be empty", department)
	}
	if config.ImageCacheNamePrefix == "" {
		return fmt.Errorf("configuration error: IMAGE_CACHE_NAME_PREFIX in department %s must not be empty", department)
	}
	return nil
}

var globalConfig Config

func Init() error {
	viper.SetConfigName("config")                  // name of config file (without extension)
	viper.SetConfigType("toml")                    // REQUIRED if the config file does not have the extension in the name
	viper.AddConfigPath("/eci-forward/pkg/config") // path to look for the config file in

	err := viper.ReadInConfig() // Find and read the config file
	if err != nil {             // Handle errors reading the config file
		return fmt.Errorf("fatal error config file: %s ", err)
	}

	err = viper.Unmarshal(&globalConfig)
	if err != nil {
		return fmt.Errorf("unable to decode into struct, %v", err)
	}
	for department, config := range globalConfig.ECI {
		err = checkConfig(department, config)
		if err != nil {
			return err
		}
	}
	return nil
}

func GetECIConfig(departmentName string) DepartmentConfig {
	return globalConfig.ECI[departmentName]
}

func GetBasicConfig() BasicConfig {
	return globalConfig.Basic
}

func GetConfig() Config {
	return globalConfig
}
